package com.insight.modules.system.service.impl;

import cn.hutool.core.collection.CollUtil;
import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.insight.modules.system.entity.*;
import com.insight.modules.system.mapper.*;
import com.yuanqiao.insight.acore.dataReport.util.DataReportUtils;
import com.yuanqiao.insight.acore.depart.entity.SysDepart;
import com.yuanqiao.insight.acore.depart.mapper.SysDepartMapper;
import com.yuanqiao.insight.common.constant.enums.ResultCode;
import com.yuanqiao.insight.common.util.common.RedisUtils;
import io.netty.util.internal.StringUtil;
import org.apache.commons.lang3.StringUtils;
import org.apache.poi.ss.usermodel.Workbook;
import org.apache.shiro.SecurityUtils;
import org.insight.modules.system.entity.*;
import org.insight.modules.system.mapper.*;
import com.insight.common.api.vo.Result;
import com.insight.common.constant.CacheConstant;
import com.insight.common.constant.CommonConstant;
import com.insight.common.constant.FillRuleConstant;
import com.insight.common.system.vo.LoginUser;
import com.insight.common.util.FillRuleUtil;
import com.insight.common.util.YouBianCodeUtil;
import com.insight.common.util.oConvertUtils;
import com.insight.modules.system.entity.*;
import com.insight.modules.system.mapper.*;
import com.insight.modules.system.model.DepartIdModel;
import com.insight.modules.system.model.SysDepartTreeModel;
import com.insight.modules.system.service.ISysDepartService;
import com.insight.modules.system.util.ExcelUtil;
import com.insight.modules.system.util.FindsDepartsChildrenUtil;
import org.jeecgframework.poi.excel.ExcelImportUtil;
import org.jeecgframework.poi.excel.entity.ImportParams;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.cache.annotation.Cacheable;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.web.multipart.MultipartFile;

import java.io.IOException;
import java.util.*;
import java.util.concurrent.ConcurrentHashMap;
import java.util.function.Consumer;
import java.util.function.Function;
import java.util.function.Predicate;
import java.util.stream.Collectors;

/**
 * <p>
 * 部门表 服务实现类
 * <p>
 *
 * @Author Steve
 * @Since 2019-01-22
 */
@Service
public class SysDepartServiceImpl extends ServiceImpl<SysDepartMapper, SysDepart> implements ISysDepartService {

    @Autowired
    private SysUserDepartMapper userDepartMapper;
    @Autowired
    private SysDepartRoleMapper sysDepartRoleMapper;
    @Autowired
    private SysDepartPermissionMapper departPermissionMapper;
    @Autowired
    private SysDepartRolePermissionMapper departRolePermissionMapper;
    @Autowired
    private SysDepartRoleUserMapper departRoleUserMapper;
    @Autowired
    private SysUserMapper sysUserMapper;
    @Autowired
    private SysDepartMapper departMapper;
    @Autowired
    private SysProvinceCityMapper provinceCityMapper;
    @Autowired
    private RedisUtils redisUtils;
    @Autowired
    private DataReportUtils dataReportUtils;

    @Value("${platform.uniqueCode}")
    private String platformCode;

    @Override
    public List<SysDepartTreeModel> queryMyDeptTreeList(String departIds) {
        //根据部门id获取所负责部门
        LambdaQueryWrapper<SysDepart> query = new LambdaQueryWrapper<SysDepart>();
        String[] codeArr = this.getMyDeptParentOrgCode(departIds);
        for (int i = 0; i < codeArr.length; i++) {
            query.or().likeRight(SysDepart::getOrgCode, codeArr[i]);
        }
        query.eq(SysDepart::getDelFlag, CommonConstant.DEL_FLAG_0.toString());
        query.orderByAsc(SysDepart::getDepartOrder);
        //将父节点ParentId设为null
        List<SysDepart> listDepts = this.list(query);
        for (int i = 0; i < codeArr.length; i++) {
            for (SysDepart dept : listDepts) {
                if (dept.getOrgCode().equals(codeArr[i])) {
                    dept.setParentId(null);
                }
            }
        }
        // 调用wrapTreeDataToTreeList方法生成树状数据
        List<SysDepartTreeModel> listResult = FindsDepartsChildrenUtil.wrapTreeDataToTreeList(listDepts);
        return listResult;
    }

    /**
     * queryTreeList 对应 queryTreeList 查询所有的部门数据,以树结构形式响应给前端
     */
//    @Cacheable(value = CacheConstant.SYS_DEPARTS_CACHE)
    @Override
    public List<SysDepartTreeModel> queryTreeList() {
        LambdaQueryWrapper<SysDepart> query = new LambdaQueryWrapper<SysDepart>();
        query.eq(SysDepart::getDelFlag, CommonConstant.DEL_FLAG_0.toString());
        query.orderByAsc(SysDepart::getDepartOrder);
        List<SysDepart> list = this.list(query);
        // 调用wrapTreeDataToTreeList方法生成树状数据
        return FindsDepartsChildrenUtil.wrapTreeDataToTreeList(list);
    }

    /**
     * @param sysUser
     * @return
     */
    @Override
    public List<SysDepart> queryTreeList(LoginUser sysUser) {

        List<String> ids = new ArrayList<>();
        if (StringUtils.isNotEmpty(sysUser.getDepartIds())) {
            ids = Arrays.asList(sysUser.getDepartIds().split(","));
        } else {
            return new ArrayList<>();
        }
        LambdaQueryWrapper<SysDepart> query = new LambdaQueryWrapper<SysDepart>();
        query.eq(SysDepart::getDelFlag, CommonConstant.DEL_FLAG_0.toString());
        query.in(SysDepart::getId, ids);
        query.orderByAsc(SysDepart::getDepartOrder);
        List<SysDepart> initialDepartList = this.list(query);

        ArrayList<SysDepart> departList = new ArrayList<>(initialDepartList);
        for (SysDepart depart : initialDepartList) {
            departList = (ArrayList<SysDepart>) getChild(depart, departList);
        }

        return departList.stream().filter(distinctByKey(SysDepart::getId)).collect(Collectors.toList());
    }

    //获取子级单位
    private List<SysDepart> getChild(SysDepart dept, List<SysDepart> childList) {
        if (null == dept) {
            return null;
        }
        List<SysDepart> list = sysDepartService.list(new QueryWrapper<SysDepart>().eq("parent_id", dept.getId()));
        if (CollUtil.isNotEmpty(list)) {
            childList.addAll(list);
            for (int i = 0; i < list.size(); i++) {
                childList = getChild(list.get(i), childList);
            }
        }
        return childList;
    }

    /**
     * 根据集合中的对象某个属性进行过滤
     *
     * @return
     */
    private static <T> Predicate<T> distinctByKey(Function<? super T, ?> keyExtractor) {
        Set<Object> seen = ConcurrentHashMap.newKeySet();
        return t -> seen.add(keyExtractor.apply(t));
    }

    @Cacheable(value = CacheConstant.SYS_DEPART_IDS_CACHE)
    @Override
    public List<DepartIdModel> queryDepartIdTreeList() {
        LambdaQueryWrapper<SysDepart> query = new LambdaQueryWrapper<SysDepart>();
        query.eq(SysDepart::getDelFlag, CommonConstant.DEL_FLAG_0.toString());
        query.orderByAsc(SysDepart::getDepartOrder);
        List<SysDepart> list = this.list(query);
        // 调用wrapTreeDataToTreeList方法生成树状数据
        List<DepartIdModel> listResult = FindsDepartsChildrenUtil.wrapTreeDataToDepartIdTreeList(list);
        return listResult;
    }

    /**
     * saveDepartData 对应 add 保存用户在页面添加的新的部门对象数据
     */
    @Override
    @Transactional
    public Result<?> saveDepartData(SysDepart sysDepart, String username) {

        List<SysDepart> duplicateDepartList = sysDepartService.list(new QueryWrapper<SysDepart>().eq("depart_name", sysDepart.getDepartName()).or().eq("depart_name_en", sysDepart.getDepartNameEn()));
        if (CollUtil.isNotEmpty(duplicateDepartList)) {
            return Result.error("部门中文名或英文名已存在！");
        }
        if (sysDepart.getParentId() == null) {
            sysDepart.setParentId("");
        } else {
            sysDepart.setParentCode(sysDepartService.getById(sysDepart.getParentId()).getDepartNameEn());
        }

        String s = UUID.randomUUID().toString().replace("-", "");
        sysDepart.setId(s);
        // 先判断该对象有无父级ID,有则意味着不是最高级,否则意味着是最高级
        // 获取父级ID
        String parentId = sysDepart.getParentId();
        //update-begin--Author:baihailong  Date:20191209 for：部门编码规则生成器做成公用配置
        JSONObject formData = new JSONObject();
        formData.put("parentId", parentId);
        String[] codeArray = (String[]) FillRuleUtil.executeRule(FillRuleConstant.DEPART, formData);
        String orgType = null;
        //update-end--Author:baihailong  Date:20191209 for：部门编码规则生成器做成公用配置
        if (codeArray != null) {
            sysDepart.setOrgCode(codeArray[0]);
            orgType = codeArray[1];
        } else {
            sysDepart.setOrgCode(String.valueOf(UUID.randomUUID()).replace("-", ""));
        }

        sysDepart.setOrgType(String.valueOf(orgType));
        sysDepart.setCreateTime(new Date());
        sysDepart.setDelFlag(CommonConstant.DEL_FLAG_0.toString());
        if (StringUtils.isEmpty(sysDepart.getPlatformCode())) {
            sysDepart.setPlatformCode(platformCode);
        }

        // 非根节点单位执行上报
        if (StringUtils.isNotEmpty(sysDepart.getParentId())) {
            JSONObject dataObject = new JSONObject();
            dataObject.put("dataType", "depart");
            dataObject.put("operateType", "I");
            dataObject.put("data", sysDepart);
            dataReportUtils.pushData(dataObject.toJSONString());
        }

        this.save(sysDepart);

        return Result.OK("添加成功!");
    }

    public boolean saveDepartUk(SysDepart sysDepart) {
        if (sysDepart != null) {
            if (sysDepart.getParentId() == null) {
                sysDepart.setParentId("");
            }
//			String s = UUID.randomUUID().toString().replace("-", "");
            sysDepart.setId(sysDepart.getId());
            // 先判断该对象有无父级ID,有则意味着不是最高级,否则意味着是最高级
            // 获取父级ID
            String parentId = sysDepart.getParentId();
            //update-begin--Author:baihailong  Date:20191209 for：部门编码规则生成器做成公用配置
            JSONObject formData = new JSONObject();
            formData.put("parentId", parentId);
            String[] codeArray = (String[]) FillRuleUtil.executeRule(FillRuleConstant.DEPART, formData);
            String orgType = null;
            //update-end--Author:baihailong  Date:20191209 for：部门编码规则生成器做成公用配置
            if (codeArray != null) {
                sysDepart.setOrgCode(codeArray[0]);
                orgType = codeArray[1];
            } else {
                sysDepart.setOrgCode(String.valueOf(UUID.randomUUID()).replace("-", ""));

            }


            sysDepart.setOrgType(String.valueOf(orgType));
            sysDepart.setCreateTime(new Date());
            sysDepart.setDelFlag(CommonConstant.DEL_FLAG_0.toString());
            boolean save = this.save(sysDepart);
            if (!save) {
                return false;
            }

        }
        return true;
    }

    /**
     * saveDepartData 的调用方法,生成部门编码和部门类型（作废逻辑）
     *
     * @param parentId
     * @return
     * @deprecated
     */
    private String[] generateOrgCode(String parentId) {
        //update-begin--Author:Steve  Date:20190201 for：组织机构添加数据代码调整
        LambdaQueryWrapper<SysDepart> query = new LambdaQueryWrapper<SysDepart>();
        LambdaQueryWrapper<SysDepart> query1 = new LambdaQueryWrapper<SysDepart>();
        String[] strArray = new String[2];
        // 创建一个List集合,存储查询返回的所有SysDepart对象
        List<SysDepart> departList = new ArrayList<>();
        // 定义新编码字符串
        String newOrgCode = "";
        // 定义旧编码字符串
        String oldOrgCode = "";
        // 定义部门类型
        String orgType = "";
        // 如果是最高级,则查询出同级的org_code, 调用工具类生成编码并返回
        if (StringUtil.isNullOrEmpty(parentId)) {
            // 线判断数据库中的表是否为空,空则直接返回初始编码
            query1.eq(SysDepart::getParentId, "").or().isNull(SysDepart::getParentId);
            query1.orderByDesc(SysDepart::getOrgCode);
            departList = this.list(query1);
            if (departList == null || departList.size() == 0) {
                strArray[0] = YouBianCodeUtil.getNextYouBianCode(null);
                strArray[1] = "1";
                return strArray;
            } else {
                SysDepart depart = departList.get(0);
                oldOrgCode = depart.getOrgCode();
                orgType = depart.getOrgType();
                newOrgCode = YouBianCodeUtil.getNextYouBianCode(oldOrgCode);
            }
        } else { // 反之则查询出所有同级的部门,获取结果后有两种情况,有同级和没有同级
            // 封装查询同级的条件
            query.eq(SysDepart::getParentId, parentId);
            // 降序排序
            query.orderByDesc(SysDepart::getOrgCode);
            // 查询出同级部门的集合
            List<SysDepart> parentList = this.list(query);
            // 查询出父级部门
            SysDepart depart = this.getById(parentId);
            // 获取父级部门的Code
            String parentCode = depart.getOrgCode();
            // 根据父级部门类型算出当前部门的类型
            orgType = String.valueOf(Integer.valueOf(depart.getOrgType()) + 1);
            // 处理同级部门为null的情况
            if (parentList == null || parentList.size() == 0) {
                // 直接生成当前的部门编码并返回
                newOrgCode = YouBianCodeUtil.getSubYouBianCode(parentCode, null);
            } else { //处理有同级部门的情况
                // 获取同级部门的编码,利用工具类
                String subCode = parentList.get(0).getOrgCode();
                // 返回生成的当前部门编码
                newOrgCode = YouBianCodeUtil.getSubYouBianCode(parentCode, subCode);
            }
        }
        // 返回最终封装了部门编码和部门类型的数组
        strArray[0] = newOrgCode;
        strArray[1] = orgType;
        return strArray;
        //update-end--Author:Steve  Date:20190201 for：组织机构添加数据代码调整
    }


    /**
     * removeDepartDataById 对应 delete方法 根据ID删除相关部门数据
     *
     */
    /*
     * @Override
     *
     * @Transactional public boolean removeDepartDataById(String id) {
     * System.out.println("要删除的ID 为=============================>>>>>"+id); boolean
     * flag = this.removeById(id); return flag; }
     */

    /**
     * updateDepartDataById 对应 edit 根据部门主键来更新对应的部门数据
     */
    @Override
    @Transactional
    public Result<?> updateDepartDataById(SysDepart sysDepart, String username) {

        List<SysDepart> duplicateDepartList = sysDepartService.list(new QueryWrapper<SysDepart>().eq("depart_name", sysDepart.getDepartName()).or().eq("depart_name_en", sysDepart.getDepartNameEn()));
        if (CollUtil.isNotEmpty(duplicateDepartList)) {
            duplicateDepartList = duplicateDepartList.stream().filter(item -> !item.getId().equals(sysDepart.getId())).collect(Collectors.toList());
            if (CollUtil.isNotEmpty(duplicateDepartList)) {
                return Result.error("部门中文名或英文名已存在！");
            }
        }

        if ("".equals(sysDepart.getParentId())) {
            sysDepart.setParentId(null);
        } else {
            sysDepart.setParentId(sysDepart.getParentId());
            sysDepart.setParentCode(sysDepartService.getById(sysDepart.getParentId()).getDepartNameEn());
        }
        sysDepart.setUpdateTime(new Date());
        sysDepart.setUpdateBy(username);
        if (StringUtils.isEmpty(sysDepart.getPlatformCode())) {
            sysDepart.setPlatformCode(platformCode);
        }

        // 非根节点单位执行上报
        if (StringUtils.isNotEmpty(sysDepart.getParentId())) {
            JSONObject dataObject = new JSONObject();
            dataObject.put("dataType", "depart");
            dataObject.put("operateType", "U");
            dataObject.put("data", sysDepart);
            dataReportUtils.pushData(dataObject.toJSONString());
        }

        this.updateById(sysDepart);
        updateDevDepart(sysDepart.getId(), sysDepart.getCityId());

        return Result.OK("编辑成功！");
    }

    public void updateDevDepart(String departId, String cityId) {
        String address = getAddress(cityId);
        sysDepartMapper.updateDeviceDepart(departId, cityId, address);
        sysDepartMapper.updateTerminalDepart(departId, cityId, address);
    }

    private String getAddress(String cityId) {
        final SysProvinceCity sysProvinceCity = provinceCityMapper.selectById(cityId);
        if (sysProvinceCity.getLevel() == 1) {
            return sysProvinceCity.getText();
        } else {
            return getAddress(sysProvinceCity.getPid() + "") + " " + sysProvinceCity.getText();
        }
    }

    public Boolean updateDepartDataByIdUk(SysDepart sysDepart) {

//		QueryWrapper<SysDepart> queryWrapper = new QueryWrapper<>();
//		queryWrapper.eq("city_id",sysDepart.getCityId());
//		queryWrapper.eq("org_type","1");

//		SysDepart one = this.sysDepartService.getOne(queryWrapper);


        if (sysDepart != null) {
            if ("" == sysDepart.getParentId()) {
                sysDepart.setParentId(null);
            } else {
                sysDepart.setParentId(sysDepart.getParentId());
            }
            sysDepart.setUpdateTime(new Date());
            this.updateById(sysDepart);
            return true;
        } else {
            return false;
        }

    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public void deleteBatchWithChildren(List<String> ids) {
        List<String> idList = new ArrayList<String>();
        for (String id : ids) {
            idList.add(id);
            this.checkChildrenExists(id, idList);
        }

        for (String departId : idList) {
            SysDepart depart = sysDepartService.getById(departId);
            // 非根节点单位执行上报
            if (StringUtils.isNotEmpty(depart.getParentId())) {
                JSONObject dataObject = new JSONObject();
                dataObject.put("dataType", "depart");
                dataObject.put("operateType", "D");
                depart.setParentCode(sysDepartService.getById(depart.getParentId()).getDepartNameEn());
                dataObject.put("data", depart);
                dataReportUtils.pushData(dataObject.toJSONString());
            }
        }

        this.removeByIds(idList);
        //根据部门id获取部门角色id
        List<String> roleIdList = new ArrayList<>();
        LambdaQueryWrapper<SysDepartRole> query = new LambdaQueryWrapper<>();
        query.select(SysDepartRole::getId).in(SysDepartRole::getDepartId, idList);
        List<SysDepartRole> depRoleList = sysDepartRoleMapper.selectList(query);
        for (SysDepartRole deptRole : depRoleList) {
            roleIdList.add(deptRole.getId());
        }
        //根据部门id删除用户与部门关系
        userDepartMapper.delete(new LambdaQueryWrapper<SysUserDepart>().in(SysUserDepart::getDepId, idList));
        //根据部门id删除部门授权
        departPermissionMapper.delete(new LambdaQueryWrapper<SysDepartPermission>().in(SysDepartPermission::getDepartId, idList));
        //根据部门id删除部门角色
        sysDepartRoleMapper.delete(new LambdaQueryWrapper<SysDepartRole>().in(SysDepartRole::getDepartId, idList));
        if (roleIdList != null && roleIdList.size() > 0) {
            //根据角色id删除部门角色授权
            departRolePermissionMapper.delete(new LambdaQueryWrapper<SysDepartRolePermission>().in(SysDepartRolePermission::getRoleId, roleIdList));
            //根据角色id删除部门角色用户信息
            departRoleUserMapper.delete(new LambdaQueryWrapper<SysDepartRoleUser>().in(SysDepartRoleUser::getDroleId, roleIdList));
        }
    }

    @Override
    public List<String> getSubDepIdsByDepId(String departId) {
        return this.baseMapper.getSubDepIdsByDepId(departId);
    }

    @Override
    public List<String> getMySubDepIdsByDepId(String departIds) {
        //根据部门id获取所负责部门
        String[] codeArr = this.getMyDeptParentOrgCode(departIds);
        return this.baseMapper.getSubDepIdsByOrgCodes(codeArr);
    }

    /**
     * <p>
     * 根据关键字搜索相关的部门数据
     * </p>
     */
    @Override
    public List<SysDepartTreeModel> searhBy(String keyWord, String myDeptSearch, String departIds) {
        LambdaQueryWrapper<SysDepart> query = new LambdaQueryWrapper<SysDepart>();
        List<SysDepartTreeModel> newList = new ArrayList<>();
        //myDeptSearch不为空时为我的部门搜索，只搜索所负责部门
        if (!StringUtil.isNullOrEmpty(myDeptSearch)) {
            //departIds 为空普通用户或没有管理部门
            if (StringUtil.isNullOrEmpty(departIds)) {
                return newList;
            }
            //根据部门id获取所负责部门
            String[] codeArr = this.getMyDeptParentOrgCode(departIds);
            for (int i = 0; i < codeArr.length; i++) {
                query.or().likeRight(SysDepart::getOrgCode, codeArr[i]);
            }
            query.eq(SysDepart::getDelFlag, CommonConstant.DEL_FLAG_0.toString());
        }
        query.like(SysDepart::getDepartName, keyWord);
        //update-begin--Author:huangzhilin  Date:20140417 for：[bugfree号]组织机构搜索回显优化--------------------
        SysDepartTreeModel model = new SysDepartTreeModel();
        List<SysDepart> departList = this.list(query);
        if (departList.size() > 0) {
            for (SysDepart depart : departList) {
                model = new SysDepartTreeModel(depart);
                model.setChildren(null);
                //update-end--Author:huangzhilin  Date:20140417 for：[bugfree号]组织机构搜索功回显优化----------------------
                newList.add(model);
            }
            return newList;
        }
        return null;
    }

    /**
     * 根据部门id删除并且删除其可能存在的子级任何部门
     */
    @Override
    @Transactional(rollbackFor = Exception.class)
    public boolean delete(String id) {
        List<String> idList = new ArrayList<>();
        idList.add(id);
        this.checkChildrenExists(id, idList);

        for (String departId : idList) {
            SysDepart depart = sysDepartService.getById(departId);
            // 非根节点单位执行上报
            if (StringUtils.isNotEmpty(depart.getParentId())) {
                JSONObject dataObject = new JSONObject();
                dataObject.put("dataType", "depart");
                dataObject.put("operateType", "D");
                depart.setParentCode(sysDepartService.getById(depart.getParentId()).getDepartNameEn());
                dataObject.put("data", depart);
                dataReportUtils.pushData(dataObject.toJSONString());
            }
        }

        //清空部门树内存
        //FindsDepartsChildrenUtil.clearDepartIdModel();
        boolean ok = this.removeByIds(idList);
        //根据部门id获取部门角色id
        List<String> roleIdList = new ArrayList<>();
        LambdaQueryWrapper<SysDepartRole> query = new LambdaQueryWrapper<>();
        query.select(SysDepartRole::getId).in(SysDepartRole::getDepartId, idList);
        List<SysDepartRole> depRoleList = sysDepartRoleMapper.selectList(query);
        for (SysDepartRole deptRole : depRoleList) {
            roleIdList.add(deptRole.getId());
        }
        //根据部门id删除用户与部门关系
        userDepartMapper.delete(new LambdaQueryWrapper<SysUserDepart>().in(SysUserDepart::getDepId, idList));
        //根据部门id删除部门授权
        departPermissionMapper.delete(new LambdaQueryWrapper<SysDepartPermission>().in(SysDepartPermission::getDepartId, idList));
        //根据部门id删除部门角色
        sysDepartRoleMapper.delete(new LambdaQueryWrapper<SysDepartRole>().in(SysDepartRole::getDepartId, idList));
        if (!roleIdList.isEmpty()) {
            //根据角色id删除部门角色授权
            departRolePermissionMapper.delete(new LambdaQueryWrapper<SysDepartRolePermission>().in(SysDepartRolePermission::getRoleId, roleIdList));
            //根据角色id删除部门角色用户信息
            departRoleUserMapper.delete(new LambdaQueryWrapper<SysDepartRoleUser>().in(SysDepartRoleUser::getDroleId, roleIdList));
        }
        return ok;
    }

    /**
     * delete 方法调用
     *
     * @param id
     * @param idList
     */
    private void checkChildrenExists(String id, List<String> idList) {
        LambdaQueryWrapper<SysDepart> query = new LambdaQueryWrapper<SysDepart>();
        query.eq(SysDepart::getParentId, id);
        List<SysDepart> departList = this.list(query);
        if (departList != null && departList.size() > 0) {
            for (SysDepart depart : departList) {
                idList.add(depart.getId());
                this.checkChildrenExists(depart.getId(), idList);
            }
        }
    }

    @Override
    public List<SysDepart> queryUserDeparts(String userId) {
        return baseMapper.queryUserDeparts(userId);
    }

    @Override
    public List<SysDepart> queryDepartsByUsername(String username) {
        return baseMapper.queryDepartsByUsername(username);
    }

    /**
     * 根据用户所负责部门ids获取父级部门编码
     *
     * @param departIds
     * @return
     */
    @Override
    public String[] getMyDeptParentOrgCode(String departIds) {
        //根据部门id查询所负责部门
        LambdaQueryWrapper<SysDepart> query = new LambdaQueryWrapper<SysDepart>();
        query.eq(SysDepart::getDelFlag, CommonConstant.DEL_FLAG_0.toString());
        query.in(SysDepart::getId, Arrays.asList(departIds.split(",")));
        query.orderByAsc(SysDepart::getOrgCode);
        List<SysDepart> list = this.list(query);
        //查找根部门
        if (list == null || list.size() == 0) {
            return new String[0];
        }
        String orgCode = this.getMyDeptParentNode(list);
        String[] codeArr = orgCode.split(",");
        return codeArr;
    }

    /**
     * 获取负责部门父节点
     *
     * @param list
     * @return
     */
    private String getMyDeptParentNode(List<SysDepart> list) {
        Map<String, String> map = new HashMap<>();
        //1.先将同一公司归类
        for (SysDepart dept : list) {
            String code = dept.getOrgCode().substring(0, 3);
            if (map.containsKey(code)) {
                String mapCode = map.get(code) + "," + dept.getOrgCode();
                map.put(code, mapCode);
            } else {
                map.put(code, dept.getOrgCode());
            }
        }
        StringBuilder parentOrgCode = new StringBuilder();
        //2.获取同一公司的根节点
        for (String str : map.values()) {
            String[] arrStr = str.split(",");
            parentOrgCode.append(',').append(this.getMinLengthNode(arrStr));
        }
        return parentOrgCode.substring(1);
    }

    /**
     * 获取同一公司中部门编码长度最小的部门
     *
     * @param str
     * @return
     */
    private String getMinLengthNode(String[] str) {
        int min = str[0].length();
        String orgCode = str[0];
        for (int i = 1; i < str.length; i++) {
            if (str[i].length() <= min) {
                min = str[i].length();
                orgCode = orgCode + "," + str[i];
            }
        }
        return orgCode;
    }

    /**
     * 获取部门树信息根据关键字
     *
     * @param keyWord
     * @return
     */
    @Override
    public List<SysDepartTreeModel> queryTreeByKeyWord(String keyWord) {
        LambdaQueryWrapper<SysDepart> query = new LambdaQueryWrapper<SysDepart>();
        query.eq(SysDepart::getDelFlag, CommonConstant.DEL_FLAG_0.toString());
        query.orderByAsc(SysDepart::getDepartOrder);
        List<SysDepart> list = this.list(query);
        // 调用wrapTreeDataToTreeList方法生成树状数据
        List<SysDepartTreeModel> listResult = FindsDepartsChildrenUtil.wrapTreeDataToTreeList(list);
        List<SysDepartTreeModel> treelist = new ArrayList<>();
        if (StringUtils.isNotBlank(keyWord)) {
            this.getTreeByKeyWord(keyWord, listResult, treelist);
        } else {
            return listResult;
        }
        return treelist;
    }

    /**
     * 根据关键字筛选部门信息
     *
     * @param keyWord
     * @return
     */
    public void getTreeByKeyWord(String keyWord, List<SysDepartTreeModel> allResult, List<SysDepartTreeModel> newResult) {
        for (SysDepartTreeModel model : allResult) {
            if (model.getDepartName().contains(keyWord)) {
                newResult.add(model);
                continue;
            } else if (model.getChildren() != null) {
                getTreeByKeyWord(keyWord, model.getChildren(), newResult);
            }
        }
    }

    @Override
    public Map<String, String> getDepartMap() {
        List<SysDepart> list = this.baseMapper.getDepMap();
        Map<String, String> map = new HashMap<>();
        list.forEach(item -> {
            map.put(item.getId(), item.getDepartName());
        });
        return map;
    }

    @Override
    public String selectNameById(String departmentId) {
        return departMapper.selectNameById(departmentId);
    }

    /**
     * 通过部门的code获取部门
     *
     * @param orgCode 部门的code码
     * @return
     */
    @Override
    public List<SysDepart> getSysDepartByOrgCode(String orgCode) {
        return departMapper.getSysDepartByOrgCode(orgCode);
    }

    @Override
    public SysDepart getDepartByOrgCode(String orgCode) {
        return departMapper.getDepartByOrgCode(orgCode);
    }

    @Override
    public List<SysDepart> getDepLists(LoginUser sysUser) {
        List<SysDepart> supList = new ArrayList<>();
        if (null != sysUser && StringUtils.isNotBlank(sysUser.getOrgCode())) {
            List<SysDepart> thisList = departMapper.getSysDepartByOrgCode(sysUser.getOrgCode());
            if (null != thisList && 0 < thisList.size()) {
                String pid = departMapper.getSysDepartByOrgCode(sysUser.getOrgCode()).get(0).getParentId();
                supList = departMapper.getSysDepartByPidAndType(pid, "4");
                if (0 == supList.size()) {
                    supList = departMapper.getSysDepartByPidAndType(departMapper.getSysDepartByOrgCode(sysUser.getOrgCode()).get(0).getId(), "4");
                }
            }
        } else {
            QueryWrapper<SysDepart> queryWrapper = new QueryWrapper<>();
            queryWrapper.eq("org_category", "4");
            queryWrapper.orderByDesc("create_time");
            supList = this.list(queryWrapper);
        }
        return supList;
    }

    @Autowired
    private SysDepartServiceImpl sysDepartService;

    @Override
    public Result importSheets(MultipartFile file) {
        try {
            if (file == null) {
                return Result.error("文件不能为空");
            }
            Workbook hssfWorkbook = ExcelUtil.getWorkBook(file);
            if (hssfWorkbook == null) {
                return Result.error("无法读取工作簿");
            }
            ImportParams params = new ImportParams();
            int count = 2;
            QueryWrapper<SysDepart> queryWrapper = new QueryWrapper<>();
            LoginUser loginUser = (LoginUser) SecurityUtils.getSubject().getPrincipal();
            if (loginUser == null) {
                return Result.error("用户未登录");
            }
            for (int numSheet = 0; numSheet < hssfWorkbook.getNumberOfSheets(); numSheet++) {
                params.setTitleRows(0);
                params.setHeadRows(1);
                params.setNeedSave(true);
                List<SysDepart> list = ExcelImportUtil.importExcel(file.getInputStream(), SysDepart.class, params);
                if (list == null || list.isEmpty()) {
                    return Result.error("文件不能为空");
                }
                for (SysDepart sysDepart : list) {
                    if (sysDepart == null) {
                        continue;
                    }
                    count += 1;
                    if (sysDepart.getDepartName() == null) {
                        return Result.error("第" + count + "行：机构/部门名称不能为空");
                    }
                    queryWrapper.eq("depart_name", sysDepart.getDepartName());
                    List<SysDepart> list1 = sysDepartService != null ? sysDepartService.list(queryWrapper) : null;
                    if (list1 != null && !list1.isEmpty()) {
                        return Result.error("机构/部门名称存在");
                    }
                    Result<?> result = this.saveDepartData(sysDepart, loginUser.getUsername());
                    if (!result.isSuccess()) {
                        return result;
                    }
                }
            }
            return Result.ok("文件导入成功！");
        } catch (IOException e) {
            e.printStackTrace();
            return Result.error("文件导入失败:" + e.getMessage());
        } catch (Exception e) {
            e.printStackTrace();
        } finally {
            try {
                if (file != null) {
                    file.getInputStream().close();
                }
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
        return Result.error("文件导入失败!");
    }

    @Autowired
    private SysDepartMapper sysDepartMapper;

    @Override
    public String testMove(String id) {

        LinkedList<SysDepart> list = new LinkedList<>();


        List<SysDepart> city = sysDepartMapper.findCity(id);
        for (SysDepart sysDepart : city) {
            sysDepart.setOrgCategory("1"); // 组织机构
            sysDepart.setOrgType("1");
            sysDepart.setOrgCode(String.valueOf(UUID.randomUUID()).replace("-", ""));
            sysDepart.setHasChild("1");
            sysDepart.setDelFlag("0");
        }
        this.sysDepartService.saveBatch(city);

        for (SysDepart sysDepart : city) {
            List<SysDepart> sysDeparts = sysDepartMapper.findDeptByCity(sysDepart.getCityId());


            for (SysDepart sysDepart1 : sysDeparts) {
                sysDepart1.setOrgCategory("1"); // 组织机构
                sysDepart1.setOrgType("2");
                sysDepart1.setMobile(sysDepart1.getMobile());
                sysDepart1.setAddress(sysDepart1.getAddress());
                sysDepart1.setCityId(sysDepart.getCityId());
                if (StringUtils.isEmpty(sysDepart1.getOrgCode())) {
                    sysDepart1.setOrgCode(String.valueOf(UUID.randomUUID()).replace("-", ""));
                }

                sysDepart1.setHasChild("0");
                sysDepart1.setDelFlag("0");
                sysDepart1.setParentId(sysDepart.getId());
            }
            list.addAll(sysDeparts);

        }
        sysDepartMapper.del();


        this.sysDepartService.saveBatch(list);

        return "成功";
    }

    @Override
    public int syncDepart(cn.hutool.json.JSONObject depart) {
        //<!--操作类型 -->
        String operType = depart.getStr("oper");
        //<!--机构名称-->
        String name = depart.getStr("name");
        final String standardname = depart.getStr("standardname");
        name = StringUtils.isNotBlank(standardname) ? standardname : name;
        //<!--机构唯一标识-->
        String departId = depart.getStr("id");
        //<!--上级机构唯一标识-->
        String pid = depart.getStr("pid");

        if (StringUtils.isEmpty(departId)) {
            log.error("缺少机构唯一标识");
            return ResultCode.CODE_801.getCode();
        }
        if (StringUtils.isEmpty(name)) {
            log.error("机构名称为空");
            return ResultCode.CODE_801.getCode();
        }

        ResultCode resultCode = ResultCode.CODE_1;
        switch (operType) {
            case "add":
                //增加操作
                if (isExistDepartById(departId)) {
                    // 校验增加机构唯一标识是否重复 如重复 return -101
                    resultCode = ResultCode.CODE_101;
                } else if (StringUtils.isNotBlank(pid) && !isExistDepartById(pid)) {
                    //校验增加机构的上级机构是否存在  如不存在 return -102
                    resultCode = ResultCode.CODE_102;
                } else if (isExistDepartByName(name)) {
                    //校验增加机构时同级机构名称是否重复  如已存在 return -103
                    resultCode = ResultCode.CODE_103;
                } else {
                    //执行机构信息插入数据库操作  return 1
                    SysDepart sysDepart = SysDepart.build(depart);
                    sysDepart.setDelFlag("0");
                    super.baseMapper.insert(sysDepart);
                }
                //删除机构操作
                break;
            case "del":
                if (!isExistDepartById(departId)) {
                    //校验机构唯一标识对应的机构是否存在 如不存在 return -201
                    resultCode = ResultCode.CODE_201;
                } else if (isExistDepartByPid(departId)) {
                    //校验删除的机构下是否存在子机构  如存在 return -202
                    resultCode = ResultCode.CODE_202;
                } else if (isExistUser(departId)) {
                    //校验删除的机构下是否存在用户  如存在 return -203
                    resultCode = ResultCode.CODE_203;
                } else {
                    //执行删除机构信息的数据库操作  return 1
                    super.baseMapper.deleteLogic(departId);
                }
                //修改操作
                break;
            case "mod":
                if (!isExistDepartById(departId)) {
                    //校验机构唯一标识对应的机构是否存在 如不存在 return -301
                    resultCode = ResultCode.CODE_301;
                } else if (StringUtils.isNotBlank(pid) && !isExistDepartById(pid)) {
                    //校验修改机构的上级机构不存在  如不存在 return -302
                    resultCode = ResultCode.CODE_302;
                } else if (isExistDepart(departId, name)) {
                    //校验修改机构时同级机构名称重复  如存在 return -303
                    resultCode = ResultCode.CODE_303;
                } else {
                    //执行修改机构信息的数据库操作  return 1
                    SysDepart sysDepart = SysDepart.build(depart);
                    super.baseMapper.updateById(sysDepart);
                }
                break;
            default:
                resultCode = ResultCode.CODE_803;
        }
        return resultCode.getCode();
    }

    @Override
    public List<SysDepart> queryByCodes(String[] departCode) {
        return this.baseMapper.queryByCodes(departCode);
    }

    /**
     * 根据parentId查询部门树
     *
     * @param parentId
     * @param ids      前端回显传递
     * @return
     */
    @Override
    public List<SysDepartTreeModel> queryTreeListByPid(String parentId, String ids) {
        Consumer<LambdaQueryWrapper<SysDepart>> square = i -> {
            if (oConvertUtils.isNotEmpty(ids)) {
                i.in(SysDepart::getId, ids.split(","));
            } else {
                if (oConvertUtils.isEmpty(parentId)) {
                    i.and(q -> q.isNull(true, SysDepart::getParentId).or().eq(true, SysDepart::getParentId, ""));
                } else {
                    i.eq(true, SysDepart::getParentId, parentId);
                }
            }
        };
        LambdaQueryWrapper<SysDepart> lqw = new LambdaQueryWrapper();
        lqw.eq(true, SysDepart::getDelFlag, CommonConstant.DEL_FLAG_0.toString());
        lqw.func(square);
        lqw.orderByDesc(SysDepart::getDepartOrder);
        List<SysDepart> list = list(lqw);
        //update-begin---author:wangshuai ---date:20220316  for：[JTC-119]在部门管理菜单下设置部门负责人 创建用户的时候不需要处理
        //设置用户id,让前台显示
        this.setUserIdsByDepList(list);
        //update-end---author:wangshuai ---date:20220316  for：[JTC-119]在部门管理菜单下设置部门负责人 创建用户的时候不需要处理
        List<SysDepartTreeModel> records = new ArrayList<>();
        for (int i = 0; i < list.size(); i++) {
            SysDepart depart = list.get(i);
            SysDepartTreeModel treeModel = new SysDepartTreeModel(depart);
            //TODO 异步树加载key拼接__+时间戳,以便于每次展开节点会刷新数据
            //treeModel.setKey(treeModel.getKey()+"__"+System.currentTimeMillis());
            treeModel.setKey(treeModel.getKey());
            Integer count = this.baseMapper.queryCountByPid(depart.getId());
            if (count > 0) {
                treeModel.setIsLeaf(false);
            } else {
                treeModel.setIsLeaf(true);
            }
            records.add(treeModel);
        }
        return records;
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public void syncZJGDepart(List<SysDepart> sysDeparts) {
        super.baseMapper.delete(new LambdaQueryWrapper<>());
        this.saveBatch(sysDeparts);
        redisUtils.del(CacheConstant.SYS_DEPARTS_CACHE);
    }

    @Override
    public List<SysDepart> queryListByAreaId(List<String> areaIdList) {
        return this.baseMapper.queryListByAreaId(areaIdList);
    }

    /**
     * 通过部门集合为部门设置用户id，用于前台展示
     *
     * @param departList 部门集合
     */
    private void setUserIdsByDepList(List<SysDepart> departList) {
        //查询负责部门不为空的情况
        LambdaQueryWrapper<SysUsers> query = new LambdaQueryWrapper<>();
        query.isNotNull(SysUsers::getDepartIds);
        List<SysUsers> users = sysUserMapper.selectList(query);
        Map<String, Object> map = new HashMap(5);
        //先循环一遍找到不同的负责部门id
        for (SysUsers user : users) {
            String departIds = user.getDepartIds();
            String[] departIdArray = departIds.split(",");
            for (String departId : departIdArray) {
                //mao中包含部门key，负责用户直接拼接
                if (map.containsKey(departId)) {
                    String userIds = map.get(departId) + "," + user.getId();
                    map.put(departId, userIds);
                } else {
                    map.put(departId, user.getId());
                }
            }
        }
        //循环部门集合找到部门id对应的负责用户
        for (SysDepart sysDepart : departList) {
            if (map.containsKey(sysDepart.getId())) {
                sysDepart.setDirectorUserIds(map.get(sysDepart.getId()).toString());
            }
        }
    }

    private boolean isExistDepartById(String departId) {
        return isExistDepart(departId, null, null, false);
    }

    private boolean isExistDepartByName(String departName) {
        return isExistDepart(null, departName, null, false);
    }

    private boolean isExistDepartByPid(String pid) {
        return isExistDepart(null, null, pid, false);
    }

    private boolean isExistDepart(String departId, String departName) {
        return isExistDepart(departId, departName, null, true);
    }

    private boolean isExistDepart(String departId, String departName, String pid, boolean isMod) {
        final LambdaQueryWrapper<SysDepart> wrapper = new LambdaQueryWrapper<>();

        if (StringUtils.isNotBlank(departId)) {
            if (isMod) {
                wrapper.ne(SysDepart::getId, departId);
            } else {
                wrapper.eq(SysDepart::getId, departId);
            }
        }
        if (StringUtils.isNotBlank(departName)) {
            wrapper.eq(SysDepart::getDepartName, departName);
        }
        if (StringUtils.isNotBlank(pid)) {
            wrapper.eq(SysDepart::getParentId, pid);
        }

        wrapper.eq(SysDepart::getDelFlag, 0);
        return baseMapper.selectCount(wrapper) > 0;
    }

    private boolean isExistUser(String departId) {
        final LambdaQueryWrapper<SysUsers> wrapper = new LambdaQueryWrapper<SysUsers>()
                .like(SysUsers::getDepartIds, departId)
                .eq(SysUsers::getDelFlag, 0);
        return sysUserMapper.selectCount(wrapper) > 0;
    }

    public void syncZyDepart(JSONArray org, boolean isFirst) {
        if (CollUtil.isEmpty(org)) {
            return;
        }
        org.stream()
                .map(obj -> (JSONObject) obj)
                .sorted(Comparator.comparingLong(item -> item.getLong("timestamp")))
                .forEach(orgObj -> {
                    final Integer type = orgObj.getInteger("type");
                    SysDepart sysDepart = SysDepart.build(orgObj);
                    switch (type) {
                        case 0:
                            super.baseMapper.deleteById(sysDepart.getId());
                            break;
                        case 1:
                            if (!isFirst) {
                                final SysDepart depart = super.baseMapper.selectById(sysDepart.getId());
                                if (depart == null) {
                                    super.baseMapper.insert(sysDepart);
                                } else {
                                    super.baseMapper.updateById(sysDepart);
                                }
                                break;
                            }
                        case 2:
                            super.baseMapper.insert(sysDepart);
                            break;
                        default:
                    }
                });
        redisUtils.del(CacheConstant.SYS_DEPARTS_CACHE);
    }
}
